//
//  UpgradeLayer.cpp
//  ATM Killer
//
//  Created by Cloner Team on 9/9/14.
//
//

#include "UpgradeLayer.h"
UpgradeLayer::UpgradeLayer() {
    this->gameModel = GameModel::getInstance();
    this->avatarDict = __Dictionary::create();
    CC_SAFE_RETAIN(this->avatarDict);
    this->cardArray = __Array::create();
    CC_SAFE_RETAIN(this->cardArray);
    this->pageButtons = __Array::create();
    CC_SAFE_RETAIN(this->pageButtons);
    this->currentCharacterID = 0;
    this->currentUpgradeID = 1;
    this->currentChoosenPage = 0;
    this->isPopUpShow = false;
    this->isSkipPopUpShow = false;
    this->initialize();
    this->createLayers();
    this->createLayersContent();
}

UpgradeLayer::~UpgradeLayer() {
    Utils::safeRelease(this->avatarDict);
    Utils::safeRelease(this->pageButtons);
    Utils::safeRelease(this->cardArray);
}

void UpgradeLayer::onEnter() {
    Layer::onEnter();
    this->touchesRegister();
}

void UpgradeLayer::onExit() {
    Layer::onExit();
    this->removeAllChildrenWithCleanup(true);
}

void UpgradeLayer::touchesRegister() {
    auto listener = EventListenerTouchAllAtOnce::create();
    listener->onTouchesBegan = CC_CALLBACK_2(UpgradeLayer::onTouchesBegan, this);
    listener->onTouchesMoved = CC_CALLBACK_2(UpgradeLayer::onTouchesMoved, this);
    listener->onTouchesEnded = CC_CALLBACK_2(UpgradeLayer::onTouchesEnded, this);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}

void UpgradeLayer::onTouchesBegan(const std::vector<Touch*>& touches, Event* event)
{
    if (this->gameModel->getGameState() == GS_UPGRADE && this->cardDirection == NUM_CARDS_HALT && this->isPopUpShow == false) {
        for(auto touch : touches){
            Point point = this->convertTouchToNodeSpace(touch);
            Point characterBoardPoint = point - Point(this->characterBoard->getPositionX() - this->characterBoard->getContentSize().width/2, this->characterBoard->getPositionY() - this->characterBoard->getContentSize().height/2);
            //check current pageButton
            //            for(int i = 0; i < this->pageButtons->count(); i++) {
            //                Face* pageButtonFace = (Face*) this->pageButtons->getObjectAtIndex(i);
            //                RectBody* pageButtonRect = new RectBody(pageButtonFace->getContentSize().width, pageButtonFace->getContentSize().height);
            //                pageButtonRect->setPosition(Point(pageButtonFace->getPositionX(), pageButtonFace->getPositionY()));
            //                if (Utils::checkPointInRect(pageButtonRect, characterBoardPoint)) {
            //                    this->currentChoosenPage = i;
            //                }
            //            }
            //check current upgrade ID
            for(int i = 0; i < this->cardArray->count(); i++) {
                Face* cardFace = (Face*) this->cardArray->getObjectAtIndex(i);
                if(this->cardContentView->isNodeVisible(cardFace)) {
                    RectBody* cardRect = new RectBody(cardFace->getContentSize().width, cardFace->getContentSize().height);
                    cardRect->setPosition(Point(cardFace->getPositionX() + cardContentView->getPositionX(), cardFace->getPositionY() + cardContentView->getPositionY()) + this->cardContentView->getContentOffset());
                    if (cardFace->isVisible()==true && Utils::checkPointInRect(cardRect, characterBoardPoint)) {
                        this->cardChoice = i;
                    }
                }
            }
            
            //check avatars
            __Array* allKeys = this->avatarDict->allKeys();
            for(int i = 0; i < this->avatarDict->count(); i++) {
                __Integer* key = (__Integer*)allKeys->getObjectAtIndex(i);
                Face* avatarFace = (Face*) this->avatarDict->objectForKey(key->getValue());
                if (this->avatarContentView->isNodeVisible(avatarFace)) {
                    RectBody* avatarRect = new RectBody(avatarFace->getContentSize().width - 15, avatarFace->getContentSize().height - 15);
                    avatarRect->setPosition(Point(avatarFace->getPositionX() + avatarContentView->getPositionX(), avatarFace->getPositionY() + avatarContentView->getPositionY()) + this->avatarContentView->getContentOffset());
                    if (Utils::checkPointInRect(avatarRect, point)) {
                        this->avatarChoice = key->getValue();
                    }
                }
            }
            //check swipe
            RectBody* cardsRegion = new RectBody(410, 310);
            cardsRegion->setPosition(Point(230,220));
            if (Utils::checkPointInRect(cardsRegion, characterBoardPoint)) {
                this->swipe = true;
                this->timeOfSwipe = 0.0f;
                this->pointSwipe = point;
            }
        }
    }
}

void UpgradeLayer::onTouchesMoved(const std::vector<Touch*>& touches, Event* event) {
    if (this->gameModel->getGameState() == GS_UPGRADE && this->cardDirection == NUM_CARDS_HALT) {
        for(auto touch : touches){
            Point point = this->convertTouchToNodeSpace(touch);
            float distance = Utils::distance(point, this->pointSwipe);
            if(distance > 50) {
                this->cardChoice = -1;
            }
        }
        
    }
}

void UpgradeLayer::onTouchesEnded(const std::vector<Touch*>& touches, Event* event) {
    if (this->gameModel->getGameState() == GS_UPGRADE && this->cardDirection == NUM_CARDS_HALT && this->isPopUpShow == false) {
        for(auto touch : touches){
            Point point = this->convertTouchToNodeSpace(touch);
            Point characterBoardPoint = point - Point(this->characterBoard->getPositionX() - this->characterBoard->getContentSize().width/2, this->characterBoard->getPositionY() - this->characterBoard->getContentSize().height/2);
            //check avatars
            __Array* allKeys = this->avatarDict->allKeys();
            for(int i = 0; i < this->avatarDict->count(); i++) {
                __Integer* key = (__Integer*)allKeys->getObjectAtIndex(i);
                Face* avatarFace = (Face*) this->avatarDict->objectForKey(key->getValue());
                if (this->avatarContentView->isNodeVisible(avatarFace)) {
                    RectBody* avatarRect = new RectBody(avatarFace->getContentSize().width - 15, avatarFace->getContentSize().height - 15);
                    avatarRect->setPosition(Point(avatarFace->getPositionX() + avatarContentView->getPositionX(), avatarFace->getPositionY() + avatarContentView->getPositionY()) + this->avatarContentView->getContentOffset());
                    if (Utils::checkPointInRect(avatarRect, point)) {
                        if (this->avatarChoice == key->getValue()){
                            this->currentCharacterID = avatarFace->getTag();
                            this->notify(REQ_CHANGE_CHARACTER, EVT_CLICK_BUTTON, NULL, 0, NULL);
                        }
                    }
                }
            }
            //check swipe
            RectBody* cardsRegion = new RectBody(410, 310);
            cardsRegion->setPosition(Point(230,220));
            float distance = Utils::distance(point, this->pointSwipe);
            float speed = distance / this->timeOfSwipe;
            if (this->swipe == true ) {
                if (speed > 150 && distance >= 70) { // change page
                    if (point.x > this->pointSwipe.x){
                        if (this->currentChoosenPage > 0) {
                            this->currentChoosenPage -- ;
                            this->finishContentOffset = this->currentChoosenPage * (-392);
                            this->contentOffsetSpeed = 98;
                            this->cardDirection = NUM_CARDS_RIGHT;
                        }
                    }
                    if (point.x < this->pointSwipe.x){
                        if (this->currentChoosenPage < this->pageButtons->count() - 1) {
                            this->currentChoosenPage ++;
                            this->finishContentOffset = this->currentChoosenPage * (-392);
                            this->contentOffsetSpeed = -98;
                            this->cardDirection = NUM_CARDS_LEFT;
                        }
                    }
                }
            }
            //card choice
            for(int i = 0; i < this->cardArray->count(); i++) {
                Face* cardFace = (Face*) this->cardArray->getObjectAtIndex(i);
                RectBody* cardRect = new RectBody(cardFace->getContentSize().width, cardFace->getContentSize().height);
                cardRect->setPosition(Point(cardFace->getPositionX() + cardContentView->getPositionX(), cardFace->getPositionY() + cardContentView->getPositionY()) + this->cardContentView->getContentOffset());
                if (cardFace->isVisible()==true && Utils::checkPointInRect(cardRect, characterBoardPoint)) {
                    if (this->cardChoice == i) {
                        this->currentUpgradeID = cardFace->getTag();
                    }
                }
            }
            this->swipe = false;
            this->avatarChoice = -1;
            
        }
    }
}

void UpgradeLayer::initialize() {
    //upgrade listener
    this->upgradeListener = UpgradeListener::create();
    this->upgradeListener->setHandlerObj(this);
    this->upgradeListener->setChangeCharacter(ug_listener_func(UpgradeLayer::onChangeCharacter));
    this->gameModel->addListener(this->upgradeListener);
    
    //notification listener
    this->notiListener = NotificationListener::create();
    this->notiListener->setHandlerObj(this);
    this->notiListener->setShowNotification(ug_listener_func(UpgradeLayer::onShowNotification));
    this->notiListener->setRemoveNotification(ug_listener_func(UpgradeLayer::onRemoveNotification));
    this->gameModel->addListener(this->notiListener);
}

void UpgradeLayer::createLayers() {
    this->grayLayer = UGLayerColor::create();
    this->grayLayer->initWithColor(Color4B(0,0,0,100));
    this->addChild(this->grayLayer);
    this->grayLayer->setVisible(false);
    
    this->mainLayer = UGLayer::create();
    this->addChild(this->mainLayer);
    
    this->avatarLayer = UGLayer::create();
    
    this->cardsLayer = UGLayer::create();
    
    this->popUpLayer = UGLayer::create();
    this->addChild(this->popUpLayer);
}

void UpgradeLayer::createLayersContent() {
    //load character board
    this->loadCharacterBoard();
    //load popUp Face
    this->loadPopUp();
}

void UpgradeLayer::loadCharacterBoard() {
    Size gameSize = this->gameModel->getDisplayResolutionSize();
    
    //create characterBoard
    this->characterBoard = new Face();
    this->characterBoard->initWithSpriteFrameName(ANI_BOARD_GUI);
    this->characterBoard->setPosition(gameSize.width/2 + 30,gameSize.height/2);
    this->mainLayer->addChild(this->characterBoard,10);
    //character title
    Label* characterTitle = Utils::createLabel((char*)"Characters Upgrade", (char*)FONT_TRANSFORMER, 32);
    characterTitle->setPosition(this->characterBoard->getContentSize().width/2 - 130,this->characterBoard->getContentSize().height - 35);
    this->characterBoard->addChild(characterTitle);
    //money bar
    Face* moneyBar = new Face();
    moneyBar->initWithSpriteFrameName(ANI_MONEY_BAR);
    moneyBar->setPosition(this->characterBoard->getContentSize().width - moneyBar->getContentSize().width/2 - 25, this->characterBoard->getContentSize().height - 30);
    this->characterBoard->addChild(moneyBar);
    
    this->currentMoneyLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 28);
    this->currentMoneyLabel->setDimensions(300, this->currentMoneyLabel->getDimensions().height);
    this->currentMoneyLabel->setPosition(moneyBar->getContentSize().width/2 - 30, moneyBar->getContentSize().height/2 - 3);
    moneyBar->addChild(this->currentMoneyLabel);
    
    //level-holder
    Face* levelHolder = new Face();
    levelHolder->initWithSpriteFrameName(ANI_LEVEL_HOLDER);
    levelHolder->setPosition(100,500);
    this->characterBoard->addChild(levelHolder);
    
    this->levelLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 47);
    this->levelLabel->setColor(Color3B(128,215,255));
    this->levelLabel->setPosition(levelHolder->getContentSize().width/2 + 3, levelHolder->getContentSize().height/2 - 10);
    levelHolder->addChild(this->levelLabel);
    
    //level up cost label
    this->levelUpCostLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 28);
    this->levelUpCostLabel->setAnchorPoint(Point(1,0));
    this->levelUpCostLabel->setPosition(818,515);
    this->levelUpCostLabel->setColor(Color3B(255,174,7));
    this->levelUpCostLabel->setDimensions(400, this->levelUpCostLabel->getContentSize().height);
    this->levelUpCostLabel->setHorizontalAlignment(TextHAlignment::RIGHT);
    this->characterBoard->addChild(this->levelUpCostLabel);
    
    //level up button
    UGMenu* buttonMenu = UGMenu::create();
    buttonMenu->setPosition(Point::ZERO);
    this->characterBoard->addChild(buttonMenu);
    
    this->levelUpButton = Utils::createButton((char*)ANI_BUTTON_LEVEL_UP_1, (char*)ANI_BUTTON_LEVEL_UP_2);
    this->levelUpButton->setPosition(655,480);
    buttonMenu->addChild(this->levelUpButton);
    this->levelUpButton->setCallback(CC_CALLBACK_1(UpgradeLayer::showLevelUpPopUp, this));
    
    this->hireButton = Utils::createButton((char*)ANI_BUTTON_HIRE_THIS_STAFF_1, (char*)ANI_BUTTON_HIRE_THIS_STAFF_2);
    this->hireButton->setPosition(655,480);
    buttonMenu->addChild(this->hireButton);
    this->hireButton->setCallback(CC_CALLBACK_1(UpgradeLayer::showLevelUpPopUp, this));
    
    //purchase button
    this->purchaseButton = Utils::createButton((char*)ANI_BUTTON_PURCHASE_1, (char*) ANI_BUTTON_PURCHASE_2);
    this->purchaseButton->setPosition(655,140);
    buttonMenu->addChild(this->purchaseButton);
    this->purchaseButton->setCallback(CC_CALLBACK_1(UpgradeLayer::showUpgradePopUp,this));
    
    //continue button
    this->continueButton = Utils::createButton((char*)ANI_BUTTON_CONTINUE_1, (char*)ANI_BUTTON_CONTINUE_2);
    this->continueButton->setPosition(655,67);
    buttonMenu->addChild(this->continueButton);
    this->continueButton->setCallback(CC_CALLBACK_1(UpgradeLayer::onButtonClick,this));
    
    //skip button
    this->skipButton = Utils::createButton((char*)ANI_BUTTON_SKIP_1, (char*)ANI_BUTTON_SKIP_2);
    this->skipButton->setPosition(460,530);
    buttonMenu->addChild(this->skipButton);
    this->skipButton->setCallback(CC_CALLBACK_1(UpgradeLayer::showSkipTimePopUp,this));
    //character
    //name
    this->characterNameLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 32);
    this->characterNameLabel->setAnchorPoint(Point(0,0.5));
    this->characterNameLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->characterNameLabel->setPosition(Point(170, 535));
    this->characterNameLabel->setDimensions(400, this->characterNameLabel->getContentSize().height);
    this->characterBoard->addChild(characterNameLabel);
    //mps
    this->characterMpsLabel = Utils::createLabel((char*)"0", (char*)FONT_MYRIADPRO_BOLD , 18);
    this->characterMpsLabel->setAnchorPoint(Point(0,0.5));
    this->characterMpsLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->characterMpsLabel->setColor(Color3B(128,215,255));
    this->characterMpsLabel->setPosition(Point(170,507));
    this->characterMpsLabel->setDimensions(400, this->characterMpsLabel->getContentSize().height);
    this->characterBoard->addChild(this->characterMpsLabel);
    //time to next upgrade
    this->timeUpgradeLabel = Utils::createLabel((char*)"Time to buy next upgrade:", (char*)FONT_MYRIADPRO_BOLD , 18);
    this->timeUpgradeLabel->setAnchorPoint(Point(0,0.5));
    this->timeUpgradeLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->timeUpgradeLabel->setColor(Color3B(128,215,255));
    this->timeUpgradeLabel->setPosition(Point(170, 484));
    this->characterBoard->addChild(this->timeUpgradeLabel);
    //totalAtmBonusLabel
    this->totalAtmBonusLabel = Utils::createLabel((char*)"Total bonus of the ATM:", (char*)FONT_MYRIADPRO_BOLD , 18);
    this->totalAtmBonusLabel->setAnchorPoint(Point(0,0.5));
    this->totalAtmBonusLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->totalAtmBonusLabel->setColor(Color3B(128,215,255));
    this->totalAtmBonusLabel->setPosition(Point(170, 484));
    this->totalAtmBonusLabel->setDimensions(400, this->totalAtmBonusLabel->getContentSize().height);
    this->characterBoard->addChild(this->totalAtmBonusLabel);
    //time clock
    this->timeClockLabel = Utils::createLabel((char*)"0", (char*)FONT_MYRIADPRO_BOLD, 18);
    this->timeClockLabel->setAnchorPoint(Point(1,0.5));
    this->timeClockLabel->setHorizontalAlignment(TextHAlignment::RIGHT);
    this->timeClockLabel->setColor(Color3B(128,215,255));
    this->timeClockLabel->setPosition(Point(476,484));
    this->characterBoard->addChild(this->timeClockLabel);
    //time
    this->downBar = new Face();
    this->downBar->initWithSpriteFrameName(ANI_PROCESS_BAR_DOWN);
    this->downBar->setAnchorPoint(Point(0,0.5));
    this->downBar->setPosition(Point(170, 460));
    this->characterBoard->addChild(downBar);
    Face* progressFace = new Face();
    progressFace->initWithSpriteFrameName(ANI_PROCESS_BAR_UP);
    this->timeBar = ProgressTimer::create(progressFace);
    this->timeBar->setType(ProgressTimer::Type::BAR);
    this->timeBar->setMidpoint(Point(0,0));
    this->timeBar->setBarChangeRate(Point(1,0));
    this->timeBar->setPercentage(100);
    this->timeBar->setPosition(downBar->getContentSize().width/2, downBar->getContentSize().height/2);
    this->downBar->addChild(this->timeBar);
    //upgrade info
    //upgrade name
    this->upgradeNameLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 30);
    this->upgradeNameLabel->setDimensions(350, this->upgradeNameLabel->getDimensions().height);
    this->upgradeNameLabel->setAnchorPoint(Point(0,0));
    this->upgradeNameLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->upgradeNameLabel->setColor(Color3B(128, 215, 255));
    this->upgradeNameLabel->setPosition(490, 342);
    this->characterBoard->addChild(this->upgradeNameLabel);
    //upgrade effect
    this->upgradeEffectLabel = Utils::createLabel((char*)"0", (char*)FONT_MYRIADPRO_BOLD, 20);
    this->upgradeEffectLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->upgradeEffectLabel->setAnchorPoint(Point(0, 0));
    this->upgradeEffectLabel->setPosition(490, 310);
    this->upgradeEffectLabel->setDimensions(340, this->upgradeEffectLabel->getContentSize().height);
    this->characterBoard->addChild(this->upgradeEffectLabel);
    
    //upgrade required Label
    this->requiredLevelLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 23);
    this->requiredLevelLabel->setAnchorPoint(Point(0,1));
    this->requiredLevelLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->requiredLevelLabel->setColor(Color3B(255,174,7));
    this->requiredLevelLabel->setPosition(490,330);
    this->requiredLevelLabel->setDimensions(340, 70);
    this->characterBoard->addChild(this->requiredLevelLabel);
    
    //upgrade desc
    this->upgradeDescLabel = Utils::createLabel((char*)"0", (char*)FONT_MYRIADPRO_BOLDIT, 20);
    this->upgradeDescLabel->setAnchorPoint(Point(0, 1));
    this->upgradeDescLabel->setPosition(487, 300);
    this->upgradeDescLabel->setDimensions(340,110);
    this->upgradeDescLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->characterBoard->addChild(this->upgradeDescLabel);
    
    //upgrade cost
    this->upgradeCostLabel = Utils::createLabel((char*)"$ 0",(char*)FONT_TRANSFORMER, 28);
    this->upgradeCostLabel->setAnchorPoint(Point(1,0));
    this->upgradeCostLabel->setColor(Color3B(255,174,7));
    this->upgradeCostLabel->setPosition(810,175);
    this->upgradeCostLabel->setDimensions(300, this->upgradeCostLabel->getContentSize().height);
    this->upgradeCostLabel->setHorizontalAlignment(TextHAlignment::RIGHT);
    this->characterBoard->addChild(this->upgradeCostLabel);
    
    //cards
    this->createCards();
    this->arrangeCards();
    this->cardContentView = ScrollView::create(Size(380, 400));
    this->cardContentView->setPosition(40, 0);
    this->cardContentView->setContainer(this->cardsLayer);
    this->cardContentView->setDirection(ScrollView::Direction::HORIZONTAL);
    this->cardContentView->setContentOffset(Point(0,0));
    this->cardContentView->setTouchEnabled(false);
    this->characterBoard->addChild(this->cardContentView);
    //page buttons
    this->createPageButtons();
    
    //atmavatar
    {
        Face* atmHolder = new Face();
        atmHolder->initWithSpriteFrameName((char*)ANI_AVATAR_HOLDER_2);
        atmHolder->setPosition(40, (atmHolder->getContentSize().height + 2) * (this->gameModel->getCharacters()->count() + 1) + 40);
        atmHolder->setTag(CHAR_ATM);
        
        Face* atmAvatar = new Face();
        atmAvatar->initWithSpriteFrameName(this->gameModel->getAtmInformation()->getAvatarImage());
        atmAvatar->setPosition(atmHolder->getContentSize().width/2 - 4, atmHolder->getContentSize().height/2 + 1);
        atmHolder->addChild(atmAvatar,10);
        atmAvatar->setTag(0);
        
        Face* notiFace = new Face();
        notiFace->initWithSpriteFrameName(ANI_NOTI);
        notiFace->setPosition(atmHolder->getContentSize().width - notiFace->getContentSize().width/2, atmHolder->getContentSize().height - notiFace->getContentSize().height/2);
        atmHolder->addChild(notiFace,11);
        notiFace->setTag(1);
        notiFace->setVisible(false);
        
        this->avatarLayer->addChild(atmHolder);
        this->avatarDict->setObject(atmHolder, CHAR_ATM);
    }
    //fingeravatar
    {
        Face* fingerHolder = new Face();
        fingerHolder->initWithSpriteFrameName((char*)ANI_AVATAR_HOLDER_2);
        fingerHolder->setPosition(40, (fingerHolder->getContentSize().height + 2) * this->gameModel->getCharacters()->count() + 40);
        fingerHolder->setTag(CHAR_FINGER);
        
        Face* fingerAvatar = new Face();
        fingerAvatar->initWithSpriteFrameName(this->gameModel->getFingerInformation()->getAvatarImage());
        fingerAvatar->setPosition(fingerHolder->getContentSize().width/2 - 4, fingerHolder->getContentSize().height/2 + 1);
        fingerHolder->addChild(fingerAvatar,10);
        fingerAvatar->setTag(0);
        
        Face* notiFace = new Face();
        notiFace->initWithSpriteFrameName(ANI_NOTI);
        notiFace->setPosition(fingerHolder->getContentSize().width - notiFace->getContentSize().width/2, fingerHolder->getContentSize().height - notiFace->getContentSize().height/2);
        fingerHolder->addChild(notiFace,11);
        notiFace->setTag(1);
        notiFace->setVisible(false);
        
        this->avatarLayer->addChild(fingerHolder);
        this->avatarDict->setObject(fingerHolder,CHAR_FINGER);
    }
    //characteravatars
    {
        for(int i = this->gameModel->getCharacters()->count()-1; i >= 0; i--) {
            EntityCharacter* entityCharacter = (EntityCharacter*)gameModel->getEttRepository()->getCharacterList()->objectForKey(i);
            Face* holder = new Face();
            holder->initWithSpriteFrameName((char*)ANI_AVATAR_HOLDER_2);
            holder->setPosition(40, (holder->getContentSize().height + 2) * (this->gameModel->getCharacters()->count() - i - 1) + 40);
            holder->setTag(entityCharacter->getCharacterId());
            
            Face* avatar = new Face();
            avatar->initWithSpriteFrameName(entityCharacter->getAvatarImage());
            avatar->setPosition(holder->getContentSize().width/2 - 4, holder->getContentSize().height/2+1);
            holder->addChild(avatar,10);
            avatar->setTag(0);
            
            Face* notiFace = new Face();
            notiFace->initWithSpriteFrameName(ANI_NOTI);
            notiFace->setPosition(holder->getContentSize().width - notiFace->getContentSize().width/2, holder->getContentSize().height - notiFace->getContentSize().height/2);
            notiFace->setTag(1);
            notiFace->setVisible(false);
            holder->addChild(notiFace,11);
            
            this->avatarLayer->addChild(holder);
            this->avatarDict->setObject(holder,entityCharacter->getCharacterId());
        }
    }
    this->avatarLayer->setPosition(0,0);
    int heightAvatarLayer = (int)this->avatarDict->count() * 75 + 16;
    int widthAvatarLayer = 80;
    this->avatarLayer->setContentSize(Size(widthAvatarLayer, heightAvatarLayer));
    this->avatarContentView = ScrollView::create(Size(100 , this->characterBoard->getContentSize().height - 100));
    this->avatarContentView->setPosition(this->characterBoard->getPositionX() - this->characterBoard->getContentSize().width/2 - 80, this->characterBoard->getPositionY() - this->characterBoard->getContentSize().height/2 + 32);
    
    this->avatarContentView->setContainer(this->avatarLayer);
    this->avatarContentView->setDirection(ScrollView::Direction::VERTICAL);
    this->avatarContentView->setContentOffset(Point(0, -317));
    //    this->avatarContentView->setTouchEnabled(false);
    this->mainLayer->addChild(this->avatarContentView);
    //scrollbutton
    UGMenu* scrollMenu = UGMenu::create();
    scrollMenu->setPosition(Point::ZERO);
    this->mainLayer->addChild(scrollMenu);
    
    this->scrollButtonUp = Utils::createButton((char*)ANI_BUTTON_SCROLLUP_1, (char*) ANI_BUTTON_SCROLLUP_2);
    this->scrollButtonDown = Utils::createButton((char*)ANI_BUTTON_SCROLLDOWN_1, (char*) ANI_BUTTON_SCROLLDOWN_2);
    this->scrollButtonDown->setPosition(this->avatarContentView->getPositionX() + 37, this->avatarContentView->getPositionY() - 20);
    this->scrollButtonUp->setPosition(this->avatarContentView->getPositionX() + 37,this->avatarContentView->getPositionY() + 540);
    this->scrollButtonUp->setCallback(CC_CALLBACK_1(UpgradeLayer::onButtonClick,this));
    this->scrollButtonDown->setCallback(CC_CALLBACK_1(UpgradeLayer::onButtonClick,this));
    scrollMenu->addChild(this->scrollButtonDown);
    scrollMenu->addChild(this->scrollButtonUp);
    
}

void UpgradeLayer::loadPopUp() {
    Size gameSize = this->gameModel->getDisplayResolutionSize();
    this->popUpFace = new Face();
    this->popUpFace->initWithSpriteFrameName(ANI_POP_UP_BG);
    this->popUpFace->setPosition(gameSize.width/2, gameSize.height/2);
    this->popUpLayer->addChild(this->popUpFace);
    
    Label* labelPopUp1 = Utils::createLabel((char*)"Are you sure to spend", (char*)FONT_TRANSFORMER, 28);
    labelPopUp1->setColor(Color3B(255,255,255));
    labelPopUp1->setAnchorPoint(Point(0.5,1));
    labelPopUp1->setDimensions(350, 100);
    labelPopUp1->setPosition(this->popUpFace->getContentSize().width/2, 215);
    labelPopUp1->setTag(1);
    
    Label* labelPopUp2 = Utils::createLabel((char*)"$123.456 Million", (char*)FONT_TRANSFORMER,35);
    labelPopUp2->setColor(Color3B(255,174,7));
    labelPopUp2->setPosition(this->popUpFace->getContentSize().width/2, 150);
    labelPopUp2->setTag(2);
    
    Label* labelPopUp3 = Utils::createLabel((char*)"Kid gain 34 Dps this upgrade level up to 124",(char*)FONT_MYRIADPRO_REGULAR, 17);
    labelPopUp3->setDimensions(labelPopUp1->getDimensions().width - 30, 200);
    labelPopUp3->setColor(Color3B(255,255,255));
    labelPopUp3->setAnchorPoint(Point(0.5,1));
    labelPopUp3->setPosition(this->popUpFace->getContentSize().width/2, 122);
    labelPopUp3->setTag(3);
    
    this->popUpFace->addChild(labelPopUp1);
    this->popUpFace->addChild(labelPopUp2);
    this->popUpFace->addChild(labelPopUp3);
    
    UGMenu* popUpMenu = UGMenu::create();
    popUpMenu->setPosition(Point::ZERO);
    // OK Button and Cancel button
    this->okButton = Utils::createButton((char*)ANI_BUTTON_OK_1, (char*)ANI_BUTTON_OK_2);
    this->okButton->setPosition(125,50);
    this->cancelButton = Utils::createButton((char*)ANI_BUTTON_CANCEL_1, (char*)ANI_BUTTON_CANCEL_2);
    cancelButton->setPosition(275,50);
    popUpMenu->addChild(this->okButton);
    popUpMenu->addChild(this->cancelButton);
    this->cancelButton->setCallback(CC_CALLBACK_1(UpgradeLayer::cancelPopUp,this));
    this->popUpFace->addChild(popUpMenu);
    this->popUpFace->setVisible(false);
}

void UpgradeLayer::update(float dt) {
    int currentLevel;
    int upgradeLevel;
    int requiredLevel;
    bool hasNoti;
    if(this->currentCharacterID == CHAR_ATM) {
        Atm* atm = this->gameModel->getAtm();
        upgradeLevel = atm->getBonusLevel();
        currentLevel = 1;
        hasNoti = atm->getHasNotiBonus();
    } else if(this->currentCharacterID == CHAR_FINGER) {
        Finger* finger = this->gameModel->getFinger();
        FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
        FingerUpgrade* fingerUpgrade = (FingerUpgrade*) fingerInfo->getUpgradeInfo()->getObjectAtIndex(this->currentUpgradeID);
        currentLevel = finger->getLevel();
        upgradeLevel = finger->getUpgradeLevel();
        requiredLevel = fingerUpgrade->getRequiredLevel();
        hasNoti = finger->getHasNoti();
    } else {
        Character* currentCharacter = (Character*)gameModel->getCharacters()->objectForKey(this->currentCharacterID);
        EntityCharacter* entityCharacter = (EntityCharacter*)gameModel->getEttRepository()->getCharacterList()->objectForKey(this->currentCharacterID);
        EntityCharacterAvatar* upgradeCharacterInfo = (EntityCharacterAvatar*) entityCharacter->getAvatars()->getObjectAtIndex(this->currentUpgradeID);
        currentLevel = currentCharacter->getLevel();
        upgradeLevel = currentCharacter->getUpgradeLevel();
        requiredLevel = upgradeCharacterInfo->getRequiredLevel();
        hasNoti = currentCharacter->getHasNoti();
    }
    //calculate time of swipe
    if (swipe == true) {
        this->timeOfSwipe += dt;
    }
    //contentOffsetCards
    if (this->cardDirection == NUM_CARDS_RIGHT)
    {
        if (this->cardContentView->getContentOffset().x <= this->finishContentOffset - 1) {
            this->cardContentView->setContentOffset(this->cardContentView->getContentOffset() + Point(contentOffsetSpeed, 0));
        } else {
            this->cardContentView->setContentOffset(Point(this->finishContentOffset,0));
            this->cardDirection = NUM_CARDS_HALT;
        }
        
    } else if (this->cardDirection == NUM_CARDS_LEFT) {
        if (this->cardContentView->getContentOffset().x >= this->finishContentOffset + 1) {
            this->cardContentView->setContentOffset(this->cardContentView->getContentOffset() + Point(contentOffsetSpeed, 0));
        } else {
            this->cardContentView->setContentOffset(Point(this->finishContentOffset,0));
            this->cardDirection = NUM_CARDS_HALT;
        }
    }
    //specific details base on char
    {
        if(this->currentCharacterID == CHAR_ATM) {
            this->hireButton->setVisible(false);
            this->hireButton->setEnabled(false);
            this->levelUpButton->setVisible(false);
            this->levelUpButton->setEnabled(false);
            this->levelUpCostLabel->setVisible(false);
        } else {
            this->hireButton->setVisible(true);
            this->hireButton->setEnabled(true);
            this->levelUpButton->setVisible(true);
            this->levelUpButton->setEnabled(true);
            this->levelUpCostLabel->setVisible(true);
        }
    }
    //layers base on game state
    {
        if(gameModel->getGameState()==GS_UPGRADE)
        {
            this->grayLayer->setVisible(true);
            this->mainLayer->setVisible(true);
            this->popUpLayer->setVisible(true);
            this->avatarLayer->setVisible(true);
        } else {
            this->grayLayer->setVisible(false);
            this->mainLayer->setVisible(false);
            this->popUpLayer->setVisible(false);
            this->avatarLayer->setVisible(false);
        }
    }
    //update button when pop up is showed
    {
        if (this->isPopUpShow == true) {
            this->okButton->setEnabled(true);
            this->cancelButton->setEnabled(true);
            this->purchaseButton->setEnabled(false);
            this->levelUpButton->setEnabled(false);
            this->hireButton->setEnabled(false);
            this->skipButton->setEnabled(false);
            this->scrollButtonDown->setEnabled(false);
            this->scrollButtonUp->setEnabled(false);
            this->continueButton->setEnabled(false);
        } else {
            this->okButton->setEnabled(false);
            this->cancelButton->setEnabled(false);
            this->purchaseButton->setEnabled(true);
            this->levelUpButton->setEnabled(true);
            this->hireButton->setEnabled(true);
            this->skipButton->setEnabled(true);
            this->scrollButtonDown->setEnabled(true);
            this->scrollButtonUp->setEnabled(true);
            this->continueButton->setEnabled(true);
        }
    }
    //update levelup/hire this staff
    {
        if(this->currentCharacterID != CHAR_ATM)
        {
            if(currentLevel <= 0) {
                this->levelUpButton->setVisible(false);
                this->levelUpButton->setEnabled(false);
                this->hireButton->setVisible(true);
                this->hireButton->setEnabled(true);
            } else {
                this->levelUpButton->setVisible(true);
                this->levelUpButton->setEnabled(true);
                this->hireButton->setVisible(false);
                this->hireButton->setEnabled(false);
            }
        }
    }
    //update character avatars
    {
        __Array* allKeys = this->avatarDict->allKeys();
        for(int i = 0; i < allKeys->count(); i++) {
            __Integer* key = (__Integer*)allKeys->getObjectAtIndex(i);
            if (key->getValue() == CHAR_FINGER)
            {
                Finger*  finger = gameModel->getFinger();
                Face* avatarCharacter = (Face*) this->avatarDict->objectForKey(CHAR_FINGER);
                Face* avatarImage = (Face*)avatarCharacter->getChildByTag(0);
                //update lock/unlocked
                if(finger->getLevel() <= 0) {
                    avatarImage->setVisible(false);
                } else {
                    avatarImage->setVisible(true);
                }
            } else if(key->getValue() == CHAR_ATM){
                
            } else {
                Character* character = dynamic_cast<Character*>(gameModel->getCharacters()->objectForKey(key->getValue()));
                Face* avatarCharacter = (Face*) this->avatarDict->objectForKey(character->getCharacterId());
                Face* avatarImage = (Face*)avatarCharacter->getChildByTag(0);
                //update lock/unlocked
                if(character->getLevel() <= 0) {
                    avatarImage->setVisible(false);
                } else {
                    avatarImage->setVisible(true);
                }
            }
        }
    }
    //update selected avatar
    {
        __Array* allKeys = this->avatarDict->allKeys();
        for (int i = 0; i < allKeys->count(); i++) {
            __Integer* key = (__Integer*)allKeys->getObjectAtIndex(i);
            Face* avatar = (Face*) this->avatarDict->objectForKey(key->getValue());
            if ( avatar->getTag() != this->currentCharacterID) {
                avatar->setSpriteFrame((char*)ANI_AVATAR_HOLDER_2);
            } else {
                avatar->setSpriteFrame((char*)ANI_AVATAR_HOLDER_1);
            }
        }
    }
    //update page and update arcording cards
    {
        for (int i = 0; i < this->pageButtons->count(); i++) {
            Face* pageFace = (Face*) this->pageButtons->getObjectAtIndex(i);
            pageFace->setSpriteFrame(ANI_PAGE_CHOSE_2);
        }
        if (this->pageButtons->count() > 0) {
            Face* pageFace = (Face*)this->pageButtons->getObjectAtIndex(this->currentChoosenPage);
            pageFace->setSpriteFrame(ANI_PAGE_CHOSE_1);
        }
        
    }
    //update status of cards
    {
        if(this->currentCharacterID == CHAR_ATM){
            Atm* atm = this->gameModel->getAtm();
            int bonusLevel = atm->getBonusLevel();
            bool hasNoti = atm->getHasNotiBonus();
        }
        for(int i = 0; i < this->cardArray->count(); i++){
            Face* card = (Face*)this->cardArray->getObjectAtIndex(i);
            int levelOfCard = card->getTag();
            //selected
            if (levelOfCard == this->currentUpgradeID) {
                card->setSpriteFrame(ANI_CARD_2);
            } else {
                card->setSpriteFrame(ANI_CARD_1);
            }
            //noti
            Face* notiFace = (Face*) card->getChildByTag(2);
            //status
            Face* status = (Face*) card->getChildByTag(0);
            if (currentLevel <= 0) {
                status->setSpriteFrame((char*)ANI_TAG_LOCKED);
                status->setUserData((char*)"locked");
            } else {
                if (levelOfCard <= upgradeLevel) {
                    status->setSpriteFrame((char*)ANI_TAG_PURCHASE);
                    status->setUserData((char*)"purchased");
                } else if(levelOfCard == upgradeLevel + 1){
                    if (this->currentCharacterID == CHAR_ATM) {
                        Atm* atm = this->gameModel->getAtm();
                        if(atm->getBonusAvailable() == true) {
                            status->setSpriteFrame((char*)ANI_TAG_AVAILABLE);
                            status->setUserData((char*)"available");
                            if(atm->getHasNotiBonus() == true){
                                notiFace->setVisible(true);
                            } else {
                                notiFace->setVisible(false);
                            }
                        } else {
                            status->setSpriteFrame((char*)ANI_TAG_LOCKED);
                            status->setUserData((char*)"locked");
                        }
                    }
                    else if (this->currentCharacterID == CHAR_FINGER){
                        Finger* finger = this->gameModel->getFinger();
                        if(finger->getUpgradeAvailable() == true) {
                            status->setSpriteFrame((char*)ANI_TAG_AVAILABLE);
                            status->setUserData((char*)"available");
                            if(finger->getHasNoti() == true) {
                                notiFace->setVisible(true);
                            } else {
                                notiFace->setVisible(false);
                            }
                        } else {
                            status->setSpriteFrame((char*)ANI_TAG_LOCKED);
                            status->setUserData((char*)"locked");
                        }
                    } else {
                        Character* currentCharacter = (Character*)gameModel->getCharacters()->objectForKey(this->currentCharacterID);
                        if(currentCharacter->getUpgradeAvailable() == true) {
                            status->setSpriteFrame((char*)ANI_TAG_AVAILABLE);
                            status->setUserData((char*)"available");
                            if(currentCharacter->getHasNoti() == true) {
                                notiFace->setVisible(true);
                            } else {
                                notiFace->setVisible(false);
                            }
                        } else {
                            status->setSpriteFrame((char*)ANI_TAG_LOCKED);
                            status->setUserData((char*)"locked");
                        }
                    }
                } else {
                    status->setSpriteFrame((char*)ANI_TAG_LOCKED);
                    status->setUserData((char*)"locked");
                }
            }
            //upgradeAvatar
            Face* upgradeAvatar = (Face*) card->getChildByTag(1);
            if(currentCharacterID != CHAR_ATM) {
                if (currentLevel <= 0) {
                    upgradeAvatar->setVisible(false);
                } else {
                    if (levelOfCard > upgradeLevel) {
                        upgradeAvatar->setVisible(false);
                    } else {
                        upgradeAvatar->setVisible(true);
                    }
                }
            } else {
                Face* bonusAvatar = (Face*)card->getChildByTag(1);
                if (levelOfCard > upgradeLevel) {
                    bonusAvatar->setVisible(false);
                } else {
                    bonusAvatar->setVisible(true);
                }
                
            }
            
        }
    }
    //update notification of card
    if (hasNoti == true) {
        if ( this->currentUpgradeID == upgradeLevel + 1 && this->gameModel->getGameState() == GS_UPGRADE) {
            this->notify(REQ_REMOVE_NOTIFICATION, EVT_DEFAULT, NULL, 0, __Integer::create(this->currentCharacterID));
        }
    }
    //update information
    {
        Face* card = (Face*)this->cardArray->getObjectAtIndex(this->currentUpgradeID - 1);
        Face* status = (Face*) card->getChildByTag(0);
        char* currentStatus = (char*) status->getUserData();
        //current money
        char money[100];
        char* moneyText = this->gameModel->getScore()->display();
        sprintf(money,"$ %s", moneyText);
        delete[] moneyText;
        this->currentMoneyLabel->setString(money);
        this->currentMoneyLabel->setPosition(143, 26);
        if (this->currentCharacterID == CHAR_ATM) {
            char* nameText;
            char* mpcText;
            char upgradeNameText[200];
            char upgradeEffectText[200];
            char upgradeDescText[200];
            char* requiredMoneyText;
            char* costUpgradeText;
            
            AtmInformation* atmInfo = this->gameModel->getAtmInformation();
            AtmBonus* atmBonus = (AtmBonus*) atmInfo->getBonusInfo()->getObjectAtIndex(this->currentUpgradeID);
            nameText = (char*)"ATM";
            mpcText = (char*)this->gameModel->getCounter()->getTotalSpeed()->display();
            sprintf(upgradeNameText, "%s", atmBonus->getName().c_str());
            sprintf(upgradeEffectText, "%s", atmBonus->getEffect().c_str());
            sprintf(upgradeDescText, "%s", atmBonus->getDescription().c_str());
            requiredMoneyText = atmBonus->getMoneyRequired()->display();
            costUpgradeText = atmBonus->getPrice()->display();
            
            //name
            char name[100];
            sprintf(name, "%s", nameText);
            this->characterNameLabel->setString(name);
            
            //mpc
            char mpc[100];
            sprintf(mpc,"Characters money per second: $ %s", mpcText);
            delete[] mpcText;
            this->characterMpsLabel->setString(mpc);
            //total Atm bonus
            char totalBonus[100];
            sprintf(totalBonus,"Total bonus of the ATM: %.2f %%", this->gameModel->getCounter()->getTotalBonusPercentATM());
            this->totalAtmBonusLabel->setString(totalBonus);
            this->totalAtmBonusLabel->setVisible(true);
            //time clock
            this->timeClockLabel->setVisible(false);
            this->timeUpgradeLabel->setVisible(false);
            this->timeBar->setVisible(false);
            this->downBar->setVisible(false);
            //upgrade name label
            char upgradeName[100];
            if(strcmp(currentStatus, "locked") == 0) {
                sprintf(upgradeName, "%s", "Locked Upgrade");
            } else {
                sprintf(upgradeName, "%s", upgradeNameText);
            }
            this->upgradeNameLabel->setString(upgradeName);
            
            //update effect label
            char upgradeEffect[100];
            if(strcmp(currentStatus, "locked") == 0) {
                sprintf(upgradeEffect, "%s", "\?\?\?-\?\?\?");
                this->upgradeEffectLabel->setPosition(490, 265);
            } else {
                sprintf(upgradeEffect, "%s", upgradeEffectText);
                this->upgradeEffectLabel->setPosition(490, 310);
            }
            this->upgradeEffectLabel->setString(upgradeEffect);
            
            //update required money
            if(strcmp(currentStatus, "locked") == 0) {
                char requiredMoney[100];
                sprintf(requiredMoney, "Required Total Get Money: \n$ %s", requiredMoneyText);
                this->requiredLevelLabel->setVisible(true);
                this->requiredLevelLabel->setString(requiredMoney);
                delete[]requiredMoneyText;
            } else {
                this->requiredLevelLabel->setVisible(false);
            }
            
            //upgrade desc label
            char upgradeDesc[100];
            sprintf(upgradeDesc, "%s", upgradeDescText);
            this->upgradeDescLabel->setString(upgradeDesc);
            
            if(strcmp(currentStatus, "locked") == 0) {
                this->upgradeDescLabel->setVisible(false);
            } else {
                this->upgradeDescLabel->setVisible(true);
            }
            
            //upgrade cost label
            char costUpgrade[100];
            sprintf(costUpgrade,TXT_MONEY_FORMAT, costUpgradeText);
            delete[]costUpgradeText;
            this->upgradeCostLabel->setString(costUpgrade);
            this->upgradeCostLabel->setPosition(818,175);
        } else if (this->currentCharacterID == CHAR_FINGER) {
            Finger* finger = this->gameModel->getFinger();
            FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
            FingerUpgrade* fingerUpgrade = (FingerUpgrade*) fingerInfo->getUpgradeInfo()->getObjectAtIndex(this->currentUpgradeID);
            //finger money
            
            char levelUpCost[100];
            char* costCharacter = finger->getCost()->display();
            sprintf(levelUpCost,TXT_MONEY_FORMAT, costCharacter);
            delete[] costCharacter;
            this->levelUpCostLabel->setString(levelUpCost);
            this->levelUpCostLabel->setPosition(818,515);
            //character name
            char characterName[100];
            sprintf(characterName, "%s", "Finger");
            this->characterNameLabel->setString(characterName);
            
            //character mps
            char characterMps[100];
            char* mpcText = (char*)this->gameModel->getCounter()->getMoneyPerTouch()->display();
            sprintf(characterMps,"Money per hit: $ %s", mpcText);
            delete[] mpcText;
            this->characterMpsLabel->setString(characterMps);
            
            //time to next Upgrade
            FingerUpgrade* currentFingerUpgrade = (FingerUpgrade*) fingerInfo->getUpgradeInfo()->getObjectAtIndex(finger->getUpgradeLevel());
            
            float percent = (currentFingerUpgrade->getTimeWaiting() - finger->getTimeToNextUpgrade()) / currentFingerUpgrade->getTimeWaiting();
            this->timeBar->setPercentage(percent * 100);
            //total atm bonus
            this->totalAtmBonusLabel->setVisible(false);
            //time clock
            char clock[10];
            char min[5];
            char sec[5];
            this->timeUpgradeLabel->setVisible(true);
            this->timeClockLabel->setVisible(true);
            this->timeBar->setVisible(true);
            this->downBar->setVisible(true);
            if (finger->getTimeToNextUpgrade() > 0) {
                if ((int)finger->getTimeToNextUpgrade() / 60 < 10){
                    sprintf(min,"0%d", (int)finger->getTimeToNextUpgrade()/ 60);
                } else {
                    sprintf(min,"%d", (int)finger->getTimeToNextUpgrade()/ 60);
                }
                
                if ((int)finger->getTimeToNextUpgrade() % 60 <10) {
                    sprintf(sec,"0%d", (int)finger->getTimeToNextUpgrade() % 60);
                } else {
                    sprintf(sec, "%d", (int)finger->getTimeToNextUpgrade() % 60);
                }
                sprintf(clock,"%s:%s", min,sec);
            } else {
                sprintf(clock, "%s", "READY!");
            }
            this->timeClockLabel->setString(clock);
            //character level
            char level[5];
            sprintf(level,"%d",currentLevel);
            levelLabel->setString(level);
            
            //update name label
            char upgradeName[100];
            if(strcmp(currentStatus, "locked") == 0) {
                sprintf(upgradeName, "%s", "Locked Upgrade");
            } else {
                sprintf(upgradeName, "%s", fingerUpgrade->getName().c_str());
            }
            this->upgradeNameLabel->setString(upgradeName);
            
            //update effect label
            char upgradeEffect[100];
            if(strcmp(currentStatus, "locked") == 0) {
                sprintf(upgradeEffect, "%s", "\?\?\?-\?\?\?");
                this->upgradeEffectLabel->setPosition(490, 275);
            } else {
                sprintf(upgradeEffect, "%s", fingerUpgrade->getEffect().c_str());
                this->upgradeEffectLabel->setPosition(490, 310);
            }
            this->upgradeEffectLabel->setString(upgradeEffect);
            
            //update required level
            
            if(strcmp(currentStatus, "locked") == 0) {
                char requiredLevel[100];
                sprintf(requiredLevel, "Level required: %d", fingerUpgrade->getRequiredLevel());
                this->requiredLevelLabel->setString(requiredLevel);
                this->requiredLevelLabel->setVisible(true);
            } else {
                this->requiredLevelLabel->setVisible(false);
            }
            
            //upgrade desc label
            char upgradeDescription[100];
            sprintf(upgradeDescription, "\"%s\"", fingerUpgrade->getDescription().c_str());
            this->upgradeDescLabel->setString(upgradeDescription);
            if(strcmp(currentStatus, "locked") == 0) {
                this->upgradeDescLabel->setVisible(false);
            } else {
                this->upgradeDescLabel->setVisible(true);
            }
            
            //upgrade cost label
            char costUpgrade[100];
            char* costUpgradeText = fingerUpgrade->getPrice()->display();
            sprintf(costUpgrade,TXT_MONEY_FORMAT, costUpgradeText);
            delete[]costUpgradeText;
            this->upgradeCostLabel->setString(costUpgrade);
            this->upgradeCostLabel->setPosition(818,175);
        } else {
            Character* currentCharacter = (Character*)gameModel->getCharacters()->objectForKey(this->currentCharacterID);
            EntityCharacter* entityCharacter = (EntityCharacter*)gameModel->getEttRepository()->getCharacterList()->objectForKey(this->currentCharacterID);
            EntityCharacterAvatar* upgradeInfo = (EntityCharacterAvatar*)entityCharacter->getAvatars()->getObjectAtIndex(this->currentUpgradeID);
            //character money
            char levelUpCost[100];
            char* costCharacter = currentCharacter->getCost()->display();
            sprintf(levelUpCost,TXT_MONEY_FORMAT, costCharacter);
            delete[] costCharacter;
            this->levelUpCostLabel->setString(levelUpCost);
            this->levelUpCostLabel->setPosition(818,515);
            //character name
            char characterName[100];
            sprintf(characterName, "%s", currentCharacter->getName().c_str());
            this->characterNameLabel->setString(characterName);
            
            //character mps
            char characterMps[100];
            
            if(currentCharacter->getLevel()>0) {
                char* characterMpsText;
                BigNumber* mpsNumber = currentCharacter->getDps();
                mpsNumber = this->gameModel->bonusAtm(mpsNumber);
                if(currentCharacter->getCharacterId() == CHAR_GRANDMA) {
                    mpsNumber = this->gameModel->achievementEffect(mpsNumber, ACHIEVEMENT_EFFECT_GRANDMA);
                } else if (currentCharacter->getCharacterId() == CHAR_GAME_DEV) {
                    mpsNumber = this->gameModel->achievementEffect(mpsNumber, ACHIEVEMENT_EFFECT_GAMEDEV);
                }
                mpsNumber = this->gameModel->achievementEffect(mpsNumber, ACHIEVEMENT_EFFECT_DPS);
                characterMpsText = (char*)mpsNumber->display();
                sprintf(characterMps,"Mps: $ %s", characterMpsText);
                delete[] characterMpsText;
            } else {
                sprintf(characterMps,"Mps: $ 0");
            }
            this->characterMpsLabel->setString(characterMps);
            //character level
            char level[5];
            sprintf(level,"%d",currentLevel);
            levelLabel->setString(level);
            
            //time to next Upgrade
            if(currentCharacter->getLevel() > 0) {
                EntityCharacterAvatar* currentUpgradeInfo = (EntityCharacterAvatar*)entityCharacter->getAvatars()->getObjectAtIndex(currentCharacter->getUpgradeLevel());
                float percent= (currentUpgradeInfo->getTimeWaiting() - currentCharacter->getTimeToNextUpgrade())/currentUpgradeInfo->getTimeWaiting();
                this->timeBar->setPercentage(percent * 100);
            } else {
                this->timeBar->setPercentage(0);
            }
            //total atm bonus
            this->totalAtmBonusLabel->setVisible(false);
            //time clock
            char clock[10];
            char min[5];
            char sec[5];
            this->timeClockLabel->setVisible(true);
            this->timeUpgradeLabel->setVisible(true);
            this->timeBar->setVisible(true);
            this->downBar->setVisible(true);
            if (currentCharacter->getLevel() <= 0) {
                this->timeClockLabel->setVisible(false);
            } else {
                this->timeClockLabel->setVisible(true);
            }
            if (currentCharacter->getTimeToNextUpgrade() > 0) {
                if ((int)currentCharacter->getTimeToNextUpgrade() / 60 < 10){
                    sprintf(min,"0%d", (int)currentCharacter->getTimeToNextUpgrade()/ 60);
                } else {
                    sprintf(min,"%d", (int)currentCharacter->getTimeToNextUpgrade()/ 60);
                }
                
                if ((int)currentCharacter->getTimeToNextUpgrade() % 60 <10) {
                    sprintf(sec,"0%d", (int)currentCharacter->getTimeToNextUpgrade() % 60);
                } else {
                    sprintf(sec, "%d", (int)currentCharacter->getTimeToNextUpgrade() % 60);
                }
                sprintf(clock,"%s:%s", min,sec);
            } else {
                sprintf(clock, "%s", "READY!");
            }
            this->timeClockLabel->setString(clock);
            //upgrade name label
            char upgradeName[100];
            if(strcmp(currentStatus, "locked") == 0) {
                sprintf(upgradeName, "%s", "Locked Upgrade");
            } else {
                sprintf(upgradeName, "%s", upgradeInfo->getCaption().c_str());
            }
            this->upgradeNameLabel->setString(upgradeName);
            
            //upgrade effect label
            char upgradeEffect[100];
            if(strcmp(currentStatus, "locked") == 0) {
                sprintf(upgradeEffect, "%s", "\?\?\?-\?\?\?");
                this->upgradeEffectLabel->setPosition(490, 275);
            } else {
                sprintf(upgradeEffect, "%s", upgradeInfo->getEffect().c_str());
                this->upgradeEffectLabel->setPosition(490, 310);
            }
            this->upgradeEffectLabel->setString(upgradeEffect);
            
            //upgrade required level
            
            if(strcmp(currentStatus, "locked") == 0) {
                char requiredLevel[100];
                sprintf(requiredLevel, "Required Level: %d", upgradeInfo->getRequiredLevel());
                this->requiredLevelLabel->setString(requiredLevel);
                this->requiredLevelLabel->setVisible(true);
            } else {
                this->requiredLevelLabel->setVisible(false);
            }
            
            //upgrade desc label
            char upgradeDescription[100];
            sprintf(upgradeDescription, "\"%s\"", upgradeInfo->getDescription().c_str());
            this->upgradeDescLabel->setString(upgradeDescription);
            if(strcmp(currentStatus, "locked") == 0) {
                this->upgradeDescLabel->setVisible(false);
            } else {
                this->upgradeDescLabel->setVisible(true);
            }
            
            //upgrade cost label
            char costUpgrade[100];
            char* costUpgradeText = upgradeInfo->getPrice()->display();
            sprintf(costUpgrade,TXT_MONEY_FORMAT, costUpgradeText);
            delete[]costUpgradeText;
            this->upgradeCostLabel->setString(costUpgrade);
            this->upgradeCostLabel->setPosition(818,175);
        }
    }
    
    //update status of purchase button and level up button
    {
        Face* card = (Face*)this->cardArray->getObjectAtIndex(this->currentUpgradeID -1);
        Face* status = (Face*)card->getChildByTag(0);
        char* state = (char*)status->getUserData();
        if (strcmp(state, "locked") == 0 || strcmp(state,"purchased") == 0) {
            this->purchaseButton->setVisible(false);
            this->upgradeCostLabel->setVisible(false);
        } else if (strcmp(state,"available") == 0) {
            this->purchaseButton->setVisible(true);
            this->upgradeCostLabel->setVisible(true);
        }
    }
    //update if skip time pop up appears
    {
        float remainingTime;
        if (this->currentCharacterID== CHAR_ATM) {
            remainingTime = 0;
        } else if (this->currentCharacterID == CHAR_FINGER) {
            Finger* finger = this->gameModel->getFinger();
            remainingTime = finger->getTimeToNextUpgrade();
        } else {
            Character* character = (Character*)this->gameModel->getCharacters()->objectForKey(this->currentCharacterID);
            remainingTime = character->getTimeToNextUpgrade();
        }
        
        if(remainingTime <= 0) {
            if(this->isSkipPopUpShow == true) {
                this->cancelPopUp(NULL);
            }
            this->skipButton->setVisible(false);
        } else {
            this->skipButton->setVisible(true);
        }
    }
}

void UpgradeLayer::onButtonClick(Ref* sender) {
    //scrollButtonUp/scrollButtonDown
    if(sender == this->scrollButtonUp) {
        if(this->avatarLayer->getPositionY() > this->avatarContentView->minContainerOffset().y)
            this->avatarLayer->setPosition(this->avatarLayer->getPositionX(), this->avatarLayer->getPositionY() - 31.7f);
    }
    if(sender == this->scrollButtonDown) {
        if(this->avatarLayer->getPositionY() < this->avatarContentView->maxContainerOffset().y)
            this->avatarLayer->setPosition(this->avatarLayer->getPositionX(), this->avatarLayer->getPositionY() + 31.7f);
    }
    
    if(sender == this->getOkButton()) {
        
        if (this->availablePopUp == true) {
            //level up
            if (this->getOkButton()->getTag() == 1) {
                int characterId = this->currentCharacterID;
                if( characterId == CHAR_FINGER){
                    this->notify(REQ_UPGRADE_FINGER, EVT_CLICK_BUTTON, NULL, 0, NULL);
                } else {
                    this->notify(REQ_UPGRADE_CHARACTER, EVT_CLICK_BUTTON, NULL, 0, __Integer::create(characterId));
                }
                this->cancelPopUp(sender);
            }
            //special upgrade
            if (this->getOkButton()->getTag() == 2) {
                int characterId = this->currentCharacterID;
                if( characterId == CHAR_ATM){
                    this->notify(REQ_UPGRADE_BONUS_ATM, EVT_CLICK_BUTTON, NULL, 0, NULL);
                } else if( characterId == CHAR_FINGER){
                    this->notify(REQ_SPECIAL_UPGRADE_FINGER, EVT_CLICK_BUTTON, NULL, 0, NULL);
                } else {
                    this->notify(REQ_SPECIAL_UPGRADE_CHARACTER, EVT_CLICK_BUTTON, NULL, 0, __Integer::create(characterId));
                }
                this->cancelPopUp(sender);
            }
            //skip next upgrade time
            if (this->getOkButton()->getTag() == 3) {
                int characterId = this->currentCharacterID;
                BigNumber* tempPrice = (BigNumber*)this->getOkButton()->getUserData();
                __Dictionary* dict = __Dictionary::create();
                dict->setObject(__Integer::create(characterId), "id");
                dict->setObject(tempPrice, "price");
                
                
                if(characterId == CHAR_FINGER) {
                    this->notify(REQ_SKIP_FINGER, EVT_CLICK_BUTTON, NULL, 0, dict);
                } else {
                    this->notify(REQ_SKIP_CHARACTER, EVT_CLICK_BUTTON, NULL, 0, dict);
                }
                this->cancelPopUp(sender);
            }
        } else {
            this->cancelPopUp(sender);
        }
    }
    //continue
    if(sender == this->getContinueButton()){
        this->notify(REQ_RESUME, EVT_CLICK_BUTTON, NULL, 0, NULL);
    }
    //skiptime
    if(sender == this->getSkipButton()){
        
    }
}

void UpgradeLayer::onChangeCharacter(Ref* data) {
    //remove old cards
    for(int i = 0; i < this->cardArray->count(); i++) {
        Face* card = (Face*) this->cardArray->getObjectAtIndex(i);
        card->removeFromParentAndCleanup(true);
    }
    this->cardArray->removeAllObjects();
    //create new cards
    this->createCards();
    this->arrangeCards();
    //remove old page buttons
    for(int i = 0; i < this->pageButtons->count(); i++) {
        Face* pageButton = (Face*) this->pageButtons->getObjectAtIndex(i);
        pageButton->removeFromParentAndCleanup(true);
    }
    this->pageButtons->removeAllObjects();
    //calculate number of page buttons
    this->createPageButtons();
    this->currentChoosenPage = 0;
    this->currentUpgradeID = 1;
    this->cardContentView->setContentOffset(Point(0,0));
}

void UpgradeLayer::onShowNotification(Ref* data) {
    __Integer* idInteger = (__Integer*)data;
    __Array* allKeys = this->avatarDict->allKeys();
    for(int i = 0 ; i < allKeys->count(); i++ ) {
        __Integer* key = (__Integer*)allKeys->getObjectAtIndex(i);
        Face* avatarCharacter = (Face*) this->avatarDict->objectForKey(key->getValue());
        Face* notiFace = (Face*)avatarCharacter->getChildByTag(1);
        if (idInteger->getValue() == key->getValue()) {
            notiFace->setVisible(true);
        }
    }
}

void UpgradeLayer::onRemoveNotification(Ref* data) {
    __Integer* idInteger = (__Integer*)data;
    __Array* allKeys = this->avatarDict->allKeys();
    for(int i = 0 ; i < allKeys->count(); i++ ) {
        __Integer* key = (__Integer*)allKeys->getObjectAtIndex(i);
        Face* avatarCharacter = (Face*) this->avatarDict->objectForKey(key->getValue());
        Face* notiFace = (Face*)avatarCharacter->getChildByTag(1);
        if (idInteger->getValue() == key->getValue()) {
            notiFace->setVisible(false);
        }
    }
}

void UpgradeLayer::showLevelUpPopUp(Ref* sender) {
    BigNumber* tempCost;
    BigNumber* tempMps;
    string name;
    int currentLevel;
    if(this->currentCharacterID == CHAR_FINGER) {
        Finger* finger = this->gameModel->getFinger();
        tempCost = finger->getCost();
        CC_SAFE_RETAIN(tempCost);
        currentLevel = finger->getLevel();
    } else {
        Character* currentCharacter = (Character*)gameModel->getCharacters()->objectForKey(this->currentCharacterID);
        tempCost = currentCharacter->getCost();
        tempMps = currentCharacter->getDps();
        name = currentCharacter->getName();
        currentLevel = currentCharacter->getLevel();
    }
    if(this->gameModel->getScore()->compare(tempCost)>=0){
        // set label
        char labelPopUp1Text[200];
        sprintf(labelPopUp1Text, TXT_SURE_LEVEL_UP);
        Label* labelPopUp1 = (Label*) this->popUpFace->getChildByTag(1);
        labelPopUp1->setString(labelPopUp1Text);
        labelPopUp1->setPosition(this->popUpFace->getContentSize().width/2, 205);
        
        char labelPopUp2Text[200];
        char* costCharacter = tempCost->display();
        sprintf(labelPopUp2Text,TXT_MONEY_FORMAT, costCharacter);
        delete[] costCharacter;
        Label* labelPopUp2 = (Label*)this->popUpFace->getChildByTag(2);
        labelPopUp2->setPosition(this->popUpFace->getContentSize().width/2, 150);
        labelPopUp2->setString(labelPopUp2Text);
        
        char labelPopUp3Text[200];
        if(this->currentCharacterID == CHAR_FINGER) {
            sprintf(labelPopUp3Text, TXT_HINT_FINGER_LEVEL_UP, currentLevel);
        } else {
            char* dpsCharacter = tempMps->display();
            sprintf(labelPopUp3Text,TXT_HINT_LEVEL_UP,name.c_str(),dpsCharacter, currentLevel + 1);
            delete[] dpsCharacter;
        }
        Label* labelPopUp3 = (Label*)this->popUpFace->getChildByTag(3);
        labelPopUp3->setString(labelPopUp3Text);
        labelPopUp3->setVisible(true);
        
        this->getCancelButton()->setVisible(true);
        this->getOkButton()->setPosition(125,50);
        this->availablePopUp = true;
        
    } else {
        char labelPopUp1Text[200];
        sprintf(labelPopUp1Text, TXT_NOT_ENOUGH_MONEY);
        Label* labelPopUp1 = (Label*) this->popUpFace->getChildByTag(1);
        labelPopUp1->setString(labelPopUp1Text);
        labelPopUp1->setPosition(this->popUpFace->getContentSize().width/2, 215);
        
        char labelPopUp2Text[200];
        char* costCharacter = tempCost->display();
        sprintf(labelPopUp2Text,TXT_MONEY_FORMAT, costCharacter);
        delete[] costCharacter;
        Label* labelPopUp2 = (Label*)this->popUpFace->getChildByTag(2);
        labelPopUp2->setString(labelPopUp2Text);
        labelPopUp2->setPosition(this->popUpFace->getContentSize().width/2, 110);
        
        Label* labelPopUp3 = (Label*)this->popUpFace->getChildByTag(3);
        labelPopUp3->setVisible(false);
        this->getOkButton()->setPosition(200,50);
        this->getCancelButton()->setVisible(false);
        this->availablePopUp = false;
    }
    // set callback
    this->getOkButton()->setCallback(CC_CALLBACK_1(UpgradeLayer::onButtonClick,this));
    this->getOkButton()->setTag(1);
    
    this->popUpFace->setVisible(true);
    this->isPopUpShow = true;
}

void UpgradeLayer::showUpgradePopUp(Ref* sender) {
    BigNumber* tempPrice;
    string tempEffect;
    string tempName;
    int nextUpgradeLevel;
    if (this->currentCharacterID == CHAR_ATM) {
        Atm* atm = this->gameModel->getAtm();
        AtmInformation* atmInfo = this->gameModel->getAtmInformation();
        AtmBonus* atmBonus = (AtmBonus*) atmInfo->getBonusInfo()->getObjectAtIndex(atm->getBonusLevel() + 1);
        tempPrice = atmBonus->getPrice();
        tempEffect = atmBonus->getEffect();
        tempName = "Atm";
        nextUpgradeLevel = atm->getBonusLevel() + 1;
    } else if (this->currentCharacterID == CHAR_FINGER) {
        Finger* finger = this->gameModel->getFinger();
        FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
        FingerUpgrade* fingerUpgrade = (FingerUpgrade*) fingerInfo->getUpgradeInfo()->getObjectAtIndex(finger->getUpgradeLevel()+1);
        tempPrice = fingerUpgrade->getPrice();
        tempEffect = fingerUpgrade->getEffect();
        tempName = "Finger";
        nextUpgradeLevel = finger->getUpgradeLevel() + 1;
    } else {
        Character* currentCharacter = (Character*)gameModel->getCharacters()->objectForKey(this->currentCharacterID);
        EntityCharacter* entityCharacter = (EntityCharacter*)gameModel->getEttRepository()->getCharacterList()->objectForKey(this->currentCharacterID);
        EntityCharacterAvatar* upgradeCharacterInfo = (EntityCharacterAvatar*) entityCharacter->getAvatars()->getObjectAtIndex(currentCharacter->getUpgradeLevel()+1);
        tempPrice = upgradeCharacterInfo->getPrice();
        tempEffect = upgradeCharacterInfo->getEffect();
        tempName = currentCharacter->getName();
        nextUpgradeLevel = currentCharacter->getUpgradeLevel() + 1;
    }
    if(gameModel->getScore()->compare(tempPrice)>=0)
    {
        // set label
        char labelPopUp1Text[200];
        sprintf(labelPopUp1Text, TXT_SURE_LEVEL_UP);
        Label* labelPopUp1 = (Label*) this->popUpFace->getChildByTag(1);
        labelPopUp1->setString(labelPopUp1Text);
        labelPopUp1->setPosition(this->popUpFace->getContentSize().width/2, 205);
        
        char labelPopUp2Text[200];
        char* costUpgrade = tempPrice->display();
        sprintf(labelPopUp2Text,TXT_MONEY_FORMAT, costUpgrade);
        delete[]costUpgrade;
        Label* labelPopUp2 = (Label*)this->popUpFace->getChildByTag(2);
        labelPopUp2->setPosition(this->popUpFace->getContentSize().width/2, 150);
        labelPopUp2->setString(labelPopUp2Text);
        
        char labelPopUp3Text[200];
        if(this->currentCharacterID != CHAR_ATM) {
            sprintf(labelPopUp3Text,TXT_HINT_UPGRADE, tempName.c_str(),tempEffect.c_str(), nextUpgradeLevel);
        } else {
            sprintf(labelPopUp3Text,"%s", tempEffect.c_str());
        }
        Label* labelPopUp3 = (Label*)this->popUpFace->getChildByTag(3);
        labelPopUp3->setString(labelPopUp3Text);
        labelPopUp3->setVisible(true);
        
        this->getCancelButton()->setVisible(true);
        this->getOkButton()->setPosition(125,50);
        this->availablePopUp = true;
    } else {
        char labelPopUp1Text[200];
        sprintf(labelPopUp1Text, TXT_NOT_ENOUGH_MONEY);
        Label* labelPopUp1 = (Label*) this->popUpFace->getChildByTag(1);
        labelPopUp1->setString(labelPopUp1Text);
        labelPopUp1->setPosition(this->popUpFace->getContentSize().width/2, 215);
        
        char labelPopUp2Text[200];
        char* costCharacter = tempPrice->display();
        sprintf(labelPopUp2Text,TXT_MONEY_FORMAT, costCharacter);
        delete[] costCharacter;
        Label* labelPopUp2 = (Label*)this->popUpFace->getChildByTag(2);
        labelPopUp2->setString(labelPopUp2Text);
        labelPopUp2->setPosition(this->popUpFace->getContentSize().width/2, 110);
        
        Label* labelPopUp3 = (Label*)this->popUpFace->getChildByTag(3);
        labelPopUp3->setVisible(false);
        
        this->getOkButton()->setPosition(200,50);
        this->getCancelButton()->setVisible(false);
        this->availablePopUp = false;
    }
    // set callback
    this->getOkButton()->setCallback(CC_CALLBACK_1(UpgradeLayer::onButtonClick,this));
    this->getOkButton()->setTag(2);
    
    this->popUpFace->setVisible(true);
    this->isPopUpShow = true;
    
}

void UpgradeLayer::showSkipTimePopUp(Ref* sender) {
    BigNumber* tempPrice = BigNumber::create();
    tempPrice->initialize("1000000000");
    if(this->currentCharacterID != CHAR_FINGER) {
        Character* currentCharacter = (Character*)this->gameModel->getCharacters()->objectForKey(this->currentCharacterID);
        EntityCharacter* entityCharacter = (EntityCharacter*)this->gameModel->getEttRepository()->getCharacterList()->objectForKey(this->currentCharacterID);
        EntityCharacterAvatar* avatar = (EntityCharacterAvatar*)entityCharacter->getAvatars()->getObjectAtIndex(currentCharacter->getUpgradeLevel());
        tempPrice = tempPrice->multiplyRationalNumber(avatar->getTimeWaiting() / 60);
    } else if(this->currentCharacterID == CHAR_FINGER) {
        Finger* finger = this->gameModel->getFinger();
        FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
        FingerUpgrade* fingerUpgrade = (FingerUpgrade*)fingerInfo->getUpgradeInfo()->getObjectAtIndex(finger->getUpgradeLevel());
        tempPrice = tempPrice->multiplyRationalNumber((int)fingerUpgrade->getTimeWaiting() / 60);
    }
    if(gameModel->getScore()->compare(tempPrice) >= 0) {
        // set label
        char labelPopUp1Text[200];
        sprintf(labelPopUp1Text, TXT_SURE_LEVEL_UP);
        Label* labelPopUp1 = (Label*) this->popUpFace->getChildByTag(1);
        labelPopUp1->setString(labelPopUp1Text);
        labelPopUp1->setPosition(this->popUpFace->getContentSize().width/2, 205);
        
        char labelPopUp2Text[200];
        char* costUpgrade = tempPrice->display();
        sprintf(labelPopUp2Text,TXT_MONEY_FORMAT, costUpgrade);
        delete[]costUpgrade;
        Label* labelPopUp2 = (Label*)this->popUpFace->getChildByTag(2);
        labelPopUp2->setPosition(this->popUpFace->getContentSize().width/2, 150);
        labelPopUp2->setString(labelPopUp2Text);
        
        char labelPopUp3Text[200];
        sprintf(labelPopUp3Text,TXT_HINT_SKIP);
        Label* labelPopUp3 = (Label*)this->popUpFace->getChildByTag(3);
        labelPopUp3->setString(labelPopUp3Text);
        labelPopUp3->setVisible(true);
        
        this->getCancelButton()->setVisible(true);
        this->getOkButton()->setPosition(125,50);
        this->availablePopUp = true;
    } else {
        char labelPopUp1Text[200];
        sprintf(labelPopUp1Text, TXT_NOT_ENOUGH_MONEY_SKIP);
        Label* labelPopUp1 = (Label*) this->popUpFace->getChildByTag(1);
        labelPopUp1->setString(labelPopUp1Text);
        labelPopUp1->setPosition(this->popUpFace->getContentSize().width/2, 215);
        
        char labelPopUp2Text[200];
        char* costCharacter = tempPrice->display();
        sprintf(labelPopUp2Text,TXT_MONEY_FORMAT, costCharacter);
        delete[] costCharacter;
        Label* labelPopUp2 = (Label*)this->popUpFace->getChildByTag(2);
        labelPopUp2->setString(labelPopUp2Text);
        labelPopUp2->setPosition(this->popUpFace->getContentSize().width/2, 110);
        
        Label* labelPopUp3 = (Label*)this->popUpFace->getChildByTag(3);
        labelPopUp3->setVisible(false);
        
        this->getOkButton()->setPosition(200,50);
        this->getCancelButton()->setVisible(false);
        this->availablePopUp = false;
    }
    this->getOkButton()->setCallback(CC_CALLBACK_1(UpgradeLayer::onButtonClick,this));
    CC_SAFE_RETAIN(tempPrice);
    this->getOkButton()->setUserData(tempPrice);
    this->getOkButton()->setTag(3);
    
    this->popUpFace->setVisible(true);
    this->isPopUpShow = true;
    this->isSkipPopUpShow = true;
}
void UpgradeLayer::cancelPopUp(Ref* sender) {
    this->isPopUpShow = false;
    this->isSkipPopUpShow = false;
    this->popUpFace->setVisible(false);
}

void UpgradeLayer::createCards() {
    if (this->currentCharacterID == CHAR_ATM) {
        Atm* atm = this->gameModel->getAtm();
        AtmInformation* atmInfo = this->gameModel->getAtmInformation();
        for ( int i = 1; i < atmInfo->getBonusInfo()->count(); i++) {
            AtmBonus* atmBonus = (AtmBonus*) atmInfo->getBonusInfo()->getObjectAtIndex(i);
            Face* bonusCard = new Face();
            bonusCard->initWithSpriteFrameName((char*)ANI_CARD_1);
            bonusCard->setTag(atmBonus->getBonusId());//bonus level is set in tag
            
            //upgrade avatar
            Face* bonusAvatar = new Face();
            bonusAvatar->initWithSpriteFrameName(atmBonus->getBonusAvatar());
            bonusAvatar->setPosition(Point(bonusCard->getContentSize().width/2 + 1, bonusCard->getContentSize().height/2 + 15));
            bonusCard->addChild(bonusAvatar);
            bonusAvatar->setTag(1);
            
            //status
            Face* statusCard = new Face();
            statusCard->setPosition(bonusCard->getContentSize().width/2, 10);
            if (atmBonus->getBonusId()<=atm->getBonusLevel()) {
                statusCard->initWithSpriteFrameName((char*)ANI_TAG_PURCHASE);
            } else {
                statusCard->initWithSpriteFrameName((char*)ANI_TAG_LOCKED);
            }
            statusCard->setTag(0);
            bonusCard->addChild(statusCard);
            //noti
            Face* notiFace = new Face();
            notiFace->initWithSpriteFrameName(ANI_NOTI);
            notiFace->setPosition(bonusCard->getContentSize().width - notiFace->getContentSize().width/2, bonusCard->getContentSize().height);
            bonusCard->addChild(notiFace,11);
            FiniteTimeAction* fadeInAction = FadeTo::create(0.5f,255);
            FiniteTimeAction* fadeOutAction = FadeTo::create(0.5f,100);
            ActionInterval* sequenceAction = Sequence::create(fadeOutAction, fadeInAction, NULL);
            RepeatForever* repeatAction = RepeatForever::create(sequenceAction);
            notiFace->runAction(repeatAction);
            notiFace->setTag(2);
            notiFace->setVisible(false);
            
            this->cardsLayer->addChild(bonusCard);
            this->cardArray->addObject(bonusCard);
        }
    } else if (this->currentCharacterID == CHAR_FINGER) {
        Finger* finger = this->gameModel->getFinger();
        FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
        for(int i = 1; i < fingerInfo->getUpgradeInfo()->count(); i++) {
            FingerUpgrade* fingerUpgrade = (FingerUpgrade*)fingerInfo->getUpgradeInfo()->getObjectAtIndex(i);
            Face* upgradeCard = new Face();
            upgradeCard->initWithSpriteFrameName((char*)ANI_CARD_1);
            upgradeCard->setTag(i);
            //upgrade avatar
            Face* upgradeAvatar = new Face();
            upgradeAvatar->initWithSpriteFrameName(fingerUpgrade->getUpgradeAvatar());
            upgradeAvatar->setPosition(Point(upgradeCard->getContentSize().width/2 + 1, upgradeCard->getContentSize().height/2 + 15));
            upgradeCard->addChild(upgradeAvatar);
            upgradeAvatar->setTag(1);
            //status
            Face* statusCard = new Face();
            statusCard->setPosition(upgradeCard->getContentSize().width/2,10);
            if (i <= finger->getUpgradeLevel()) {
                statusCard->initWithSpriteFrameName((char*)ANI_TAG_PURCHASE);
            } else if(i > finger->getUpgradeLevel()){
                statusCard->initWithSpriteFrameName((char*)ANI_TAG_LOCKED);
            }
            statusCard->setTag(0);
            upgradeCard->addChild(statusCard);
            //noti
            Face* notiFace = new Face();
            notiFace->initWithSpriteFrameName(ANI_NOTI);
            notiFace->setPosition(upgradeCard->getContentSize().width - notiFace->getContentSize().width/2, upgradeCard->getContentSize().height);
            upgradeCard->addChild(notiFace,11);
            FiniteTimeAction* fadeInAction = FadeTo::create(0.5f,255);
            FiniteTimeAction* fadeOutAction = FadeTo::create(0.5f,100);
            ActionInterval* sequenceAction = Sequence::create(fadeOutAction, fadeInAction, NULL);
            RepeatForever* repeatAction = RepeatForever::create(sequenceAction);
            notiFace->runAction(repeatAction);
            notiFace->setTag(2);
            notiFace->setVisible(false);
            
            this->cardsLayer->addChild(upgradeCard);
            this->cardArray->addObject(upgradeCard);
        }
    } else {
        Character* currentCharacter = (Character*)this->gameModel->getCharacters()->objectForKey(this->currentCharacterID);
        EntityCharacter* entityCharacter = (EntityCharacter*)this->gameModel->getEttRepository()->getCharacterList()->objectForKey(this->currentCharacterID);
        for(int i = 1; i < entityCharacter->getAvatars()->count(); i++){
            EntityCharacterAvatar* avatar = (EntityCharacterAvatar*)entityCharacter->getAvatars()->getObjectAtIndex(i);
            Face* upgradeCard = new Face();
            upgradeCard->initWithSpriteFrameName((char*)ANI_CARD_1);
            upgradeCard->setTag(i);
            //upgrade avatar
            Face* upgradeAvatar = new Face();
            upgradeAvatar->initWithSpriteFrameName(avatar->getUpgradeAvatar());
            upgradeAvatar->setPosition(Point(upgradeCard->getContentSize().width/2 + 1, upgradeCard->getContentSize().height/2 + 15));
            upgradeCard->addChild(upgradeAvatar);
            upgradeAvatar->setTag(1);
            //status
            Face* statusCard = new Face();
            statusCard->setPosition(upgradeCard->getContentSize().width/2,10);
            if (i <= currentCharacter->getUpgradeLevel()) {
                statusCard->initWithSpriteFrameName((char*)ANI_TAG_PURCHASE);
            } else if(i > currentCharacter->getUpgradeLevel()){
                statusCard->initWithSpriteFrameName((char*)ANI_TAG_LOCKED);
            }
            statusCard->setTag(0);
            upgradeCard->addChild(statusCard);
            //noti
            Face* notiFace = new Face();
            notiFace->initWithSpriteFrameName(ANI_NOTI);
            notiFace->setPosition(upgradeCard->getContentSize().width - notiFace->getContentSize().width/2, upgradeCard->getContentSize().height);
            upgradeCard->addChild(notiFace,11);
            FiniteTimeAction* fadeInAction = FadeTo::create(0.5f,255);
            FiniteTimeAction* fadeOutAction = FadeTo::create(0.5f,100);
            ActionInterval* sequenceAction = Sequence::create(fadeOutAction, fadeInAction, NULL);
            RepeatForever* repeatAction = RepeatForever::create(sequenceAction);
            notiFace->runAction(repeatAction);
            notiFace->setTag(2);
            notiFace->setVisible(false);
            
            this->cardsLayer->addChild(upgradeCard);
            this->cardArray->addObject(upgradeCard);
        }
    }
}
void UpgradeLayer::arrangeCards() {
    for (int i = 0; i < this->cardArray->count(); i++){
        Face* upgradeCard = (Face*)this->cardArray->getObjectAtIndex(i);
        int page = i / 6;
        int index = i % 6 ;
        int startWidth = 60 + 390 * page;
        int width = startWidth + (index % 3) * 130;
        int height = 300 - (160 * (int)(index / 3));
        upgradeCard->setPosition(width, height);
    }
}

void UpgradeLayer::createPageButtons(){
    if (currentCharacterID == CHAR_ATM) {
        AtmInformation* atmInfo = this->gameModel->getAtmInformation();
        int numberOfPage = (int)(atmInfo->getBonusInfo()->count()/6);
        if ((atmInfo->getBonusInfo()->count())%6 != 0) {
            numberOfPage +=1;
        }
        for (int i = 0; i < numberOfPage; i++) {
            Face* pageFace = new Face();
            pageFace->initWithSpriteFrameName(ANI_PAGE_CHOSE_2);
            this->characterBoard->addChild(pageFace);
            pageFace->setPosition(230 - (numberOfPage-1) * 20 + i * 40, 40);
            this->pageButtons->addObject(pageFace);
        }
    } else if (currentCharacterID == CHAR_FINGER)
    {
        FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
        int numberOfPage = (int)(fingerInfo->getUpgradeInfo()->count() - 1)/6;
        if ((fingerInfo->getUpgradeInfo()->count()-1)%6 != 0) {
            numberOfPage +=1;
        }
        for (int i = 0; i < numberOfPage; i++) {
            Face* pageFace = new Face();
            pageFace->initWithSpriteFrameName(ANI_PAGE_CHOSE_2);
            this->characterBoard->addChild(pageFace);
            pageFace->setPosition(230 - (numberOfPage-1) * 20 + i * 40, 40);
            this->pageButtons->addObject(pageFace);
        }
    } else {
        EntityCharacter* entityCharacter = (EntityCharacter*)gameModel->getEttRepository()->getCharacterList()->objectForKey(this->currentCharacterID);
        int numberOfPage = (int)(entityCharacter->getAvatars()->count() - 1)/6;
        if ((entityCharacter->getAvatars()->count() - 1) % 6 != 0) {
            numberOfPage +=1;
        }
        for (int i = 0; i < numberOfPage; i++) {
            Face* pageFace = new Face();
            pageFace->initWithSpriteFrameName(ANI_PAGE_CHOSE_2);
            this->characterBoard->addChild(pageFace);
            pageFace->setPosition(230 - (numberOfPage-1) * 20 + i * 40, 40);
            this->pageButtons->addObject(pageFace);
        }
    }
}
